From 7e9596058beeb1bed9384cc56b6a1caae6d8c4fa Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 2 Sep 2005 07:59:12 +0000 Subject: [PATCH] This patch: * adds a get_ssid ACM command that allows privileged domains to retrieve types for either a given ssid reference or a given domain id (of a running domain); this command can be used to extend access control into device domains, e.g., to control network traffic currently moving through Domain 0 uncontrolled by the ACM policy * adds a script getlabel.sh that allows users inside Dom0 to retrieve the label for a given ssid reference or a given domain id (multiple labels might map onto a single ssid reference) * cleans up label-related code in tools/security by merging common functions into labelfuncs.sh * cleans up ACM code related to above changes (eventually approximating a common coding style) Signed-off-by Reiner Sailer Signed-off by Stefan Berger --- tools/security/Makefile | 1 + tools/security/secpol_tool.c | 138 ++++++++- tools/security/setlabel.sh | 313 +++----------------- xen/acm/acm_chinesewall_hooks.c | 23 ++ xen/acm/acm_core.c | 146 +++++---- xen/acm/acm_null_hooks.c | 13 +- xen/acm/acm_policy.c | 122 ++++++-- xen/acm/acm_simple_type_enforcement_hooks.c | 42 ++- xen/common/acm_ops.c | 33 ++- xen/include/acm/acm_core.h | 9 +- xen/include/acm/acm_hooks.h | 1 + xen/include/public/acm.h | 32 +- xen/include/public/acm_ops.h | 17 +- 13 files changed, 512 insertions(+), 378 deletions(-) diff --git a/tools/security/Makefile b/tools/security/Makefile index f6654d486c..23a6eea078 100644 --- a/tools/security/Makefile +++ b/tools/security/Makefile @@ -45,6 +45,7 @@ build: mk-symlinks $(MAKE) secpol_xml2bin chmod 700 ./setlabel.sh chmod 700 ./updategrub.sh + chmod 700 ./getlabel.sh secpol_tool : secpol_tool.c secpol_compat.h $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< diff --git a/tools/security/secpol_tool.c b/tools/security/secpol_tool.c index a22908d7c0..e5d4e34298 100644 --- a/tools/security/secpol_tool.c +++ b/tools/security/secpol_tool.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,17 @@ fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ errno, strerror(errno)) +void usage(char *progname) +{ + printf("Use: %s \n" + "\t getpolicy\n" + "\t dumpstats\n" + "\t loadpolicy \n" + "\t getssid -d [-f]\n" + "\t getssid -s [-f]\n", progname); + exit(-1); +} + static inline int do_policycmd(int xc_handle, unsigned int cmd, unsigned long data) { @@ -320,7 +332,7 @@ int acm_domain_loadpolicy(int xc_handle, const char *filename) if (ret) printf - ("ERROR setting policy. Use 'xm dmesg' to see details.\n"); + ("ERROR setting policy. Try 'xm dmesg' to see details.\n"); else printf("Successfully changed policy.\n"); @@ -370,7 +382,7 @@ int acm_domain_dumpstats(int xc_handle) if (ret < 0) { - printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n"); + printf("ERROR dumping policy stats. Try 'xm dmesg' to see details.\n"); return ret; } stats = (struct acm_stats_buffer *) stats_buffer; @@ -421,18 +433,122 @@ int acm_domain_dumpstats(int xc_handle) } return ret; } +/************************ get ssidref & types ******************************/ +/* + * the ssid (types) can be looked up either by domain id or by ssidref + */ +int acm_domain_getssid(int xc_handle, int argc, char * const argv[]) +{ + /* this includes header and a set of types */ + #define MAX_SSIDBUFFER 2000 + int ret, i; + acm_op_t op; + struct acm_ssid_buffer *hdr; + unsigned char *buf; + int nice_print = 1; -/***************************** main **************************************/ + op.cmd = ACM_GETSSID; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.getssid.get_ssid_by = UNSET; + /* arguments + -d ... domain id to look up + -s ... ssidref number to look up + -f ... formatted print (scripts depend on this format) + */ + while (1) + { + int c = getopt(argc, argv, "d:s:f"); + if (c == -1) + break; + if (c == 'd') + { + if (op.u.getssid.get_ssid_by != UNSET) + usage(argv[0]); + op.u.getssid.get_ssid_by = DOMAINID; + op.u.getssid.id.domainid = strtoul(optarg, NULL, 0); + } + else if (c== 's') + { + if (op.u.getssid.get_ssid_by != UNSET) + usage(argv[0]); + op.u.getssid.get_ssid_by = SSIDREF; + op.u.getssid.id.ssidref = strtoul(optarg, NULL, 0); + } + else if (c== 'f') + { + nice_print = 0; + } + else + usage(argv[0]); + } + if (op.u.getssid.get_ssid_by == UNSET) + usage(argv[0]); + + buf = malloc(MAX_SSIDBUFFER); + if (!buf) + return -ENOMEM; + + /* dump it and then push it down into xen/acm */ + op.u.getssid.ssidbuf = buf; /* out */ + op.u.getssid.ssidbuf_size = MAX_SSIDBUFFER; + ret = do_acm_op(xc_handle, &op); -void usage(char *progname) -{ - printf("Use: %s \n" - "\t getpolicy\n" - "\t dumpstats\n" - "\t loadpolicy \n", progname); - exit(-1); + if (ret) + { + printf("ERROR getting ssidref. Try 'xm dmesg' to see details.\n"); + goto out; + } + hdr = (struct acm_ssid_buffer *)buf; + if (hdr->len > MAX_SSIDBUFFER) + { + printf("ERROR: Buffer length inconsistent (ret=%d, hdr->len=%d)!\n", + ret, hdr->len); + return -EIO; + } + if (nice_print) + { + printf("SSID: ssidref = 0x%08x \n", hdr->ssidref); + printf(" P: %s, max_types = %d\n", + ACM_POLICY_NAME(hdr->primary_policy_code), hdr->primary_max_types); + printf(" Types: "); + for (i=0; i< hdr->primary_max_types; i++) + if (buf[hdr->primary_types_offset + i]) + printf("%02x ", i); + else + printf("-- "); + printf("\n"); + + printf(" S: %s, max_types = %d\n", + ACM_POLICY_NAME(hdr->secondary_policy_code), hdr->secondary_max_types); + printf(" Types: "); + for (i=0; i< hdr->secondary_max_types; i++) + if (buf[hdr->secondary_types_offset + i]) + printf("%02x ", i); + else + printf("-- "); + printf("\n"); + } + else + { + /* formatted print for use with scripts (.sh) + * update scripts when updating here (usually + * used in combination with -d to determine a + * running domain's label + */ + printf("SSID: ssidref = 0x%08x \n", hdr->ssidref); + } + + /* return ste ssidref */ + if (hdr->primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) + ret = (hdr->ssidref) & 0xffff; + else if (hdr->secondary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) + ret = (hdr->ssidref) >> 16; + out: + return ret; } +/***************************** main **************************************/ + int main(int argc, char **argv) { @@ -459,6 +575,8 @@ int main(int argc, char **argv) if (argc != 2) usage(argv[0]); ret = acm_domain_dumpstats(acm_cmd_fd); + } else if (!strcmp(argv[1], "getssid")) { + ret = acm_domain_getssid(acm_cmd_fd, argc, argv); } else usage(argv[0]); diff --git a/tools/security/setlabel.sh b/tools/security/setlabel.sh index e0d8ed741a..9e0ec34482 100644 --- a/tools/security/setlabel.sh +++ b/tools/security/setlabel.sh @@ -34,277 +34,29 @@ if [ -z "$runbash" ]; then exec sh -c "bash $0 $*" fi +export PATH=$PATH:. +source labelfuncs.sh usage () { - echo "Usage: $0 [Option]